#include <iostream>

using namespace std;

class AA
{
public:
    virtual void show()
    {
        cout<<"AA::show"<<endl;
    }
};

class BB:public AA
{
public:
    virtual void show()
    {
        cout<<"BB::show"<<endl;
    }
};

// typeid这个运算符能帮我们查看当前变量和对象的实际类型
void test01()
{
    AA* p=new BB;
    cout<<typeid(p).name()<<endl;
    cout<<typeid(*p).name()<<endl;
    (*p).show();
    delete p;
}

/*
 static_cast:一般用于基本类型之间的转换，相当于强转
 const_cast:这个一般用于去掉常量或者增加常量限制
    只能用于指针或引用之间的转换，不能用于基本类型的转换
reinterpret_cast: 重新解释转换，不太安全，完全可以说等同于c语言中的 强制转换
    不能用于基本类型的转换
dynamic_cast：动态转换
    一般只应用于虚函数的类，且更常用于多态的时候
    相比static_cast来讲父类转换子类本身就不安全，但static_cast不会直接报错，
    而dynamic_cast会直接报错。

    只能用于有父子关系的类之间，且必须是指针或引用的转换，不能用于基本类型
 */

class Animal
{
public:
    int age=100;
    void show()
    {
        cout<<"Animal::show"<<endl;
    }
};

class Dog:public Animal
{
public:
    int age = 100;
    char sex='x';
    void show()
    {
        cout<<"Dog::show"<<endl;
    }
    void output()const
    {
        cout<<"Dog::output"<<endl;
    }
};

void test02()
{
    int val=100;
    char ch=static_cast<char>(val);
    char ch1=(char)val;
    cout<<ch<<endl;
    cout<<ch1<<endl;

    Dog dog;  // 子转父：向上转型（安全）
    Animal ins=static_cast<Animal>(dog);
    ins.show();

    Animal animal; // 父转子：向上转不安全
    Dog &dog1=static_cast<Dog&>(animal);
    dog1.show();
    dog1.output();
    cout<<dog1.sex<<endl;
}

void test03(){
    int num=10;
    const int*p= &num;
    int *pp=const_cast<int*>(p);
    *pp=100;
    cout<<num<<endl;

    int *q=&num;
    *q=200;
    const int *qq=const_cast<const int*>(q);
    // *qq=200

    const int val=100; // c++中的常量是真正意义上的常量，c中是伪常量
    // int val1= const_cast<int>(val);

    char ch='a';
    const char& ch1=ch; // 常引用
    // ch1='#'
    char& ch2=const_cast<char &>(ch1);
    ch2='*';
    cout<<ch<<endl;

    Dog dog;
    const Dog &dog1=dog;
    dog1.output();
    Dog&dog2=const_cast<Dog &>(dog1);
    dog2.show();
};

void test04()
{
    int num=10;
    int *p=&num;
    // 二进制文件流，socket通信中会使用
    char *ch=reinterpret_cast<char*>(p);
    cout<<"***"<<*ch<<"***"<<endl;
}

class A{
public:
    virtual void output(){
        cout<<"A"<<endl;
    }
};

class B:public A{
public:
    virtual void output(){
        cout<<"B"<<endl;
    }
};

void test05(){
    // A*a=new A;
    // B* b=dynamic_cast<B*>(a);

    // B* b=new B;
    // A* a=dynamic_cast<A*>(b);

    A *a=new A;
    B* b=dynamic_cast<B*>(a);
    if(b==nullptr)
    {
        cout<<"zhuanhuanshibai"<<endl;
    }else{
        b->output();
    }

    A ins;
    A &ins1=ins;
    try{
        B& ins2=dynamic_cast<B&>(ins1);
        ins2.output();
    }catch(const bad_cast& ex){
        cout<<"****->"<<ex.what()<<endl;
    }

    // 当发生多态后，dynamic_cast无论在父转子还是子转
    // 服的过程中都是安全的
    A* pp=new B;
    B* ppp=dynamic_cast<B*>(pp);
    ppp->output();
}

int main()
{
    test05();
    // test04();
    // test03();
    // test02();
   // test01();
    return 0;
}